Sorteio único de valores

Algoritmo para sortear 10 valores aleatorios entre 0 e 100 garantindo que um número não seja sorteado mais de uma vez.

Nesta implementação, estamos utilizando vetores, funções para estruturar e reaproveitar o código.

As funções implementadas, podem até fazer parte de uma classe estática utilizada para organizar o código e reaproveitar ele em outros projetos.

import java.util.Random;

public class App {
    public static void main(String[] args) {
        // criar uma estrutura para guardar 10 valores
        int ValoresSorteados[] = new int[10];

        // sorteia 10 valores e preenche no vetor
        for (int posicao = 0; posicao < ValoresSorteados.length; posicao++) { 
            ValoresSorteados[posicao] = obterNumeroAleatorioUnico( 0, 100, ValoresSorteados, posicao);
        }

        // exibe 10 valores na tela
        for (int valor : ValoresSorteados) {
            System.out.println(valor);
        }
    }

    public static boolean esteValorEstaVetor(int valores[], int ultimaPosicao, int valorSorteado){
        
        for (int i = 0; i < ultimaPosicao; i++) {
            // verifica se o valor sorteado já existe no vetor, se existir retorna true
            if (valores[i] == valorSorteado)
                return true;
        }

        // se chegar aqui é pq o valor não foi encontrado dentro do laco
        // caracterizando que o valor é unico, e nao foi sorteado ainda
        return false;
    }

    public static int obterNumeroAleatorioUnico(int minimo, int maximo, int valoresSorteados[], int ultimaPosicao){
        // estamos criando exceções customizadas pelo proprio desenvolvedor
        // na programação chamamos isto de "exceção de negócio"
        
        // impede que o valor maximo do sorteio seja menor ou igual ao valor minimo
        if (maximo <= minimo) { 
            throw new IllegalArgumentException("O valor máximo deve ser maior que o mínimo!");
        // impede que o intervalo de numeros a serem sorteados seja menor que a quantidade de valores únicos solicitados
        } else if ((maximo - minimo) < (valoresSorteados.length -1)){ 
            throw new IllegalArgumentException("Intervalo muito pequeno para a quantidade de valores únicos solicitados!");
        } 

        int valorSorteadoUnico;

        do {
            // obtém um valor aleatório
            valorSorteadoUnico = obterNumeroAleatorio(minimo, maximo);

            // garantir que o zero possa ser sorteado na primeira posição
            // como o vetor inicia com todos os valores zerados, se não fizermos esta verificação
            // o zero nunca será sorteado no primeiro sorteio
            if (ultimaPosicao == 0 && valorSorteadoUnico == 0 ) {   
               return 0;
            }
        
        // repete até que o valor sorteado seja único
        } while (esteValorEstaVetor(valoresSorteados, ultimaPosicao, valorSorteadoUnico));

        return valorSorteadoUnico;
    }

    public static int obterNumeroAleatorio(int minimo, int maximo){
        Random random = new Random();

        // + 1 é util pois o nextInt sempre sorteia de 0 até o numero informado -1
        // entao fazems +1 pra deixar mais simples para quem for usar esta funcao
        int valor = random.nextInt(maximo + 1) + minimo;
        //System.out.println("Valor sorteado: " + valor);

        return valor;
    }

}


O código a seguir é a mesma versão do anterior, no entanto não utilize funções para organizar o código. Compare os dois códigos para entender o benefício do uso de funções. Veja que nesta versão do código, é muito mais dificil entender como o código funciona.


import java.util.Random;

public class App {
    public static void main(String[] args) {
        Random random = new Random();
        int ValoresSorteados[] = new int[10];

        int minimo = 0;
        int maximo = 100;         

        // laço para repetir o sorteio de 10 valores únicos
        for (int posicao = 0; posicao < ValoresSorteados.length; posicao++) {

            int ultimaPosicao = posicao;
            int valorSorteadoUnico;

            // validações (antes eram do método obterNumeroAleatorioUnico)
            if (maximo <= minimo) {
                throw new IllegalArgumentException("O valor máximo deve ser maior que o mínimo!");
            } else if ((maximo - minimo) < (ValoresSorteados.length - 1)) {
                throw new IllegalArgumentException("Intervalo muito pequeno para a quantidade de valores únicos!");
            }

            do {
                // gerar número aleatório (antes era do método obterNumeroAleatorio)
                valorSorteadoUnico = random.nextInt(maximo + 1) + minimo;

                // permitir zero na primeira posição
                if (ultimaPosicao == 0 && valorSorteadoUnico == 0) {
                    break;
                }

                // verificar se o número já foi sorteado (antes era do método esteValorEstaVetor)
                boolean existe = false;
                for (int i = 0; i < ultimaPosicao; i++) {
                    if (ValoresSorteados[i] == valorSorteadoUnico) {
                        existe = true;
                        break;
                    }
                }

                // repetir enquanto o valor já existir
                if (!existe) {
                    break;
                }

            } while (true);

            ValoresSorteados[posicao] = valorSorteadoUnico;
        }

        // exibir valores
        for (int valor : ValoresSorteados) {
            System.out.println(valor);
        }
    }
}